/*
 * Copyright (c) 2010 Stefan Marr, Vrije Universiteit Brussel
 * <http://www.stefan-marr.de/>, <http://code.google.com/p/barriers/>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <stdio.h>
#include <pthread.h>

#include "bench/epcc.h"

/* Mutex synchronizations */
//#include "synchronizations/PthreadMutexLock.h"
//#include "synchronizations/TMCSpinLock.h"

/* Barrier synchronizations */
#include "synchronizations/PthreadBarrier.h"
//#include "synchronizations/TmcSpinBarrier.h"
//#include "synchronizations/SpinningCentralBarrier.h"
//#include "synchronizations/SpinningDisseminationBarrier.h"

/* Atomic operations */
//#include "synchronizations/FetchAndAdd.h"
//#include "synchronizations/CompareAndExchangeVal.h"
//#include "synchronizations/CompareAndExchangeBool.h"

/*
 These benchmarks are inspired by
 
 OpenMP MicroBenchmark Suite - Version 2.0
 
 And the article

 A Microbenchmark Suite for OpenMP 2.0
 J. Mark Bull and Darragh O'Neill SIGARCH Comput. Archit. News29(5):41--48(2001)
 (\cite{563656}, http://www.bibsonomy.org/bibtex/286b4f70669ea3e7fa8bc87424fed0218/gron)
 */

int main (int argc, const char * argv[]) {
#define NUM_PARTICIPANTS 2
#define LOG2_NUM_PARTICIPANTS 1
  int numParticipants = atoi(argv[1]);

  /* Mutex synchronizations */
  // PthreadMutexLock
  //EPCC<PthreadMutexLock, PARTICIPANT> epcc1(numParticipants);
  //epcc1.measureSynchronizationPerformance();

  // TMCSpinLock
  //EPCC<TMCSpinLock, PARTICIPANT> epcc2(numParticipants);
  //epcc2.measureSynchronizationPerformance();

  /* Barrier synchronizations */
  // PthreadBarrier
  EPCC<PthreadBarrier, PARTICIPANT> epcc3(numParticipants);
  epcc3.measureSynchronizationPerformance();

  // TmcSpinBarrier
  //EPCC<TmcSpinBarrier, PARTICIPANT> epcc4(numParticipants);
  //epcc4.measureSynchronizationPerformance();

  // SpinningCentralBarrier
  //EPCC<SpinningCentralBarrier, PARTICIPANT> epcc5(numParticipants);
  //epcc5.measureSynchronizationPerformance();

  // SpinningDisseminationBarrier
  //EPCC<SpinningDisseminationBarrier, PARTICIPANT> epcc6(numParticipants);
  //epcc6.measureSynchronizationPerformance();

  /* Atomic operations */
  // FetchAndAdd
  //EPCC<FetchAndAdd, PARTICIPANT> epcc7(numParticipants);
  //epcc7.measureSynchronizationPerformance();

  // CompareAndExchangeVal
  //EPCC<CompareAndExchangeVal, PARTICIPANT> epcc8(numParticipants);
  //epcc8.measureSynchronizationPerformance();

  // CompareAndExchangeBool
  //EPCC<CompareAndExchangeBool, PARTICIPANT> epcc9(numParticipants);
  //epcc9.measureSynchronizationPerformance();

  pthread_exit(NULL);
  return 0;
}
